package com.leeyu.rabbitmq.publisher;

import com.leeyu.rabbitmq.config.RabbitMQConfig;
import org.junit.jupiter.api.Test;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.nio.charset.StandardCharsets;

@SpringBootTest
public class PublisherTest {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void publish(){
        // 正常发送消息
        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE, "big.black.dog", "message");
        System.out.println("消息发送成功！");
    }

    @Test
    public void publishWithProps(){

        // 可以通过MessagePostProcessor重写postProcessMessage来往props中添加一些参数
        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE, "big.black.dog", "message", new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setCorrelationId("5678");
                return message;
            }
        });
        System.out.println("消息发送成功！");
    }

    // 通过配置文件开启confirm机制 publisher-confirm-type: correlated
    // 保证消息发送到Exchange交换机
    // 成功或失败都会触发回调
    @Test
    public void publishWithConfirm(){
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                if (ack) {
                    System.out.println("消息成功发送到Exchange！");
                } else {
                    System.out.println("消息发送到Exchange失败！");
                }
            }
        });
        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE, "big.black.dog", "message");
        System.out.println("消息发送成功！");
    }

    // 通过配置文件开启Return机制 publisher-returns: true
    // 保证消息路由
    // 如果失败会触发回调
    @Test
    public void publishWithReturn(){
        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
            @Override
            public void returnedMessage(ReturnedMessage returnedMessage) {
                String msg = new String(returnedMessage.getMessage().getBody(), StandardCharsets.UTF_8);
                System.out.println("消息：" + msg + ", 路由失败！");
            }
        });
        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE, "big.red.dog", "message");
        System.out.println("消息发送成功！");
    }

    // 保证消息持久化将deliveryMode设置为2
    // durable在构建队列时默认为true，不用管
    @Test
    public void publishWithBasicProperties(){
        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE, "big.red.dog", "message", new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                // 设置消息持久化
                message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                return message;
            }
        });
        System.out.println("消息发送成功！");
    }
}
